# Variables at the module level:
successful_hunt = [] # number of hunts that lead to 0 food earning for each round (opponent hunt)
successful_slack = [] # number of slacks that lead to 1 food earning for each round (opponent hunt)
neutral_slack = [] # number of slacks that lead to -2 food earning for each round (opponent slack)
harmful_hunt = [] # number of hunts that lead to -3 food earning for each round (opponent slack)
get_award = [] # fraction of hunts over possible hunts in a round that leads to getting award
no_of_player = []

def hunt_choices(round_number, current_food, current_reputation, m,  player_reputations):
	hunt_decisions = []
	a = 0.2
		
	global no_of_player, get_award, successful_hunt, successful_slack, neutral_slack, harmful_hunt
	no_of_player.append(len(player_reputations))
	
	# a is to determine how likely I hunt.
	# When reputation is too low or successful hunt rate is high and I have sufficient food, a is high (0.2) to increase the frequency of hunting.
	# When hunting is likely to be harmful or slacking is a generally better choice or food is getting too little, a is small (0.1) to decrease the frequency of hunting.
	# Otherwise, a is taken as 0.15
	if (current_reputation < sum(player_reputations)/len(player_reputations) or sum(successful_hunt)/(sum(harmful_hunt)+0.00000001) > 1.5) and current_food > 3*(len(player_reputations)):
		a = 0.2
	elif sum(successful_hunt)/(sum(harmful_hunt)+0.00000001) < 0.5 or sum(successful_slack)*(sum(successful_hunt)+sum(harmful_hunt))/(sum(successful_slack)+sum(neutral_slack)+0.00000001)/(sum(successful_hunt)+0.00000001) > 2 or current_food < 3*(len(player_reputations)):
		a = 0.1
	else:
		a = 0.15
	
	# For the first ten rounds, always hunt strategy is implemented to boost reputation
	# After tenth round, the decision will be based on first the value of m.
	# If m is larger than the expected number of hunters that can lead to getting award, the decision will be always slack.
	# Expected number of hunters is calculated based on the average of fractions of hunts over all possible hunts
	# that lead to getting award in all finished rounds multiplied by the number of possible hunts in the current round.
	# Otherwise, when a player's reputation is more than 0.9, suggesting that the player hunts most of the time, 
	# decision to slack is made so that I can get 1 extra food more likely by slacking while the other player hunts.
	# If a player's reputation is too low, below 0.1, decision to slack is made to avoid too much food loss.
	# If the difference between my reputation and the other player reputation is more than a 
	# Player with much higher reputation would think that it is better to slack with player with lower reputation.
	# Player with much lower reputation is more likely to slack.  Hence, it is better to slack when playing with these two groups of people.  
	if round_number < 11:
		hunt_decisions = ['h' for x in player_reputations]
	elif m > sum(get_award)/(len(get_award)+0.0000000001)*len(player_reputations)*(len(player_reputations)-1):
		hunt_decisions = ['s' for x in player_reputations]
	else:
		for x in player_reputations:
			if x > 0.9 or x < 0.1:
				hunt_decisions.append('s')
			elif abs(current_reputation - x) > a:
				hunt_decisions.append('s')
			else:
				hunt_decisions.append('h')
	    	
	return hunt_decisions

def hunt_outcomes(food_earnings):
	global successful_hunt, successful_slack, neutral_slack, harmful_hunt
	successful_hunt.append(food_earnings.count(0))
	successful_slack.append(food_earnings.count(1))
	neutral_slack.append(food_earnings.count(-2))
	harmful_hunt.append(food_earnings.count(-3))

def round_end(award, m, number_hunters):
	global get_award
	if m <= number_hunters:
		get_award.append(number_hunters/no_of_player[-1]/(no_of_player[-1] - 1))